package com.wenjh.jdmzt.protocol;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import org.apache.http.HttpException;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.helper.HttpConnection;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

import com.wenjh.jdmzt.android.synctask.ProgessCallback;
import com.wenjh.jdmzt.exception.HttpErrorCodeException;
import com.wenjh.jdmzt.exception.HttpTimeoutException;
import com.wenjh.jdmzt.exception.HttpsCertificateException;
import com.wenjh.jdmzt.service.model.Image;
import com.wenjh.jdmzt.util.IOUtils;
import com.wenjh.jdmzt.util.Log4Android;

public class HttpClient {
	private static Log4Android log = new Log4Android("HttpClient");
	
	private static String API = "http://wenjianhua.sinaapp.com/photos";
	
	/**
	 * 下载图片。如果初始不知道是第几页，就传0。
	 * @param page 返回当前页码
	 * @param list
	 * @return
	 * @throws Exception 
	 */
	public static int downloadImageList(int page, List<Image> list) throws Exception {
		Map<String, String> map = new HashMap<String, String>();
		map.put("type", 1+"");
		map.put("page", page+"");
		
		try {
			String resultString = doGet(API+"/getimage.php", map);
			
			JSONObject resultJson = new JSONObject(resultString);
			JSONArray imageJsonList = resultJson.getJSONArray("list");
			for (int i = 0; i < imageJsonList.length(); i++) {
				JSONObject imageJson = imageJsonList.getJSONObject(i);
				Image image = new Image();
				image.setUrlString(imageJson.optString("downloadurl"));
				image.setId(imageJson.optString("id"));
				image.setSupportCount(imageJson.optInt("support"));
				image.setType(1);
				image.setUnsupportCount(imageJson.optInt("unsupport"));
				list.add(image);
			}
			return resultJson.optInt("currentpage") ;
		} catch (Exception e) {
			return downloadImageList2(page, list);
		}
	}
	
	private static int downloadImageList2(int page, List<Image> list) throws Exception {
		String url = "http://jandan.net/ooxx";
		if(page > 0) {
			url = url+"/page-"+page;
		}
		
		Connection connection = HttpConnection.connect(url);
		connection.timeout(20000);
		connection.userAgent("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.52 Safari/537.17");
		Document document = connection.get();

		String currentPageString = document.select(".current-comment-page").get(0).ownText();
		int currentPage = page;
		try {
			currentPage = Integer.parseInt(currentPageString.substring(1, currentPageString.length()-1));
		} catch (Exception e) {
		}
		Elements liElements = document.select(".commentlist li");
		for (Element li : liElements) {
			String id = li.id();
			if(id == null || id.length()<8) {
				continue;
			}
			String imageid = id.substring(8, id.length());
			int supportCount = Integer.parseInt(li.getElementById("cos_support-"+imageid).ownText());
			int unsupportCount = Integer.parseInt(li.getElementById("cos_unsupport-"+imageid).ownText());
			
			Elements imageElements = li.select("p img");
			for (Element imgElement : imageElements) {
				String src = imgElement.attr("src");
				Image image = new Image();
				image.setUrlString(src);
				image.setSupportCount(supportCount);
				image.setUnsupportCount(unsupportCount);
				image.setId(imageid);
				image.setType(1);
				list.add(image);
			}
		}
		
		return currentPage;
	}
	
	public static void like(String id) throws Exception {
		String result = doGet("http://jandan.net/wp-admin/?acv_ajax=true&option=1&ID="+id, null);
		String[] array = result.split("|");
		if(array.length == 3 && !"1".equals(array[2])) {
			throw new com.wenjh.jdmzt.exception.HttpException("操作失败，因为你只能表示 '喜欢' 或 '不喜欢' 一次");
		}
	}
	
	public static void unlike(String id) throws Exception {
		String result = doGet("http://jandan.net/wp-admin/?acv_ajax=true&option=0&ID="+id, null);
		String[] array = result.split("|");
		if(array.length == 3 && !"-1".equals(array[2])) {
			throw new com.wenjh.jdmzt.exception.HttpException("操作失败，因为你只能表示 '喜欢' 或 '不喜欢' 一次");
		}
	}
	
	public static void publish(String author, String email, String imageurl) throws Exception {
//		"http://jandan.net/wp-content/themes/egg/comments-ajax.php";
//		author:wenjh
//		email:wenlin56@sina.com
//		comment:http://ww1.sinaimg.cn/bmiddle/6a517a6ajw1e1z0w7daaxj.jpg
//		comment_post_ID:21183
		
		Map<String, String> map = new HashMap<String, String>();
		map.put("author", author);
		map.put("email", email);
		map.put("comment_post_ID", new Random().nextInt(50000)+"");
		map.put("comment", imageurl+"");
		
		String result = doPost("http://jandan.net/wp-content/themes/egg/comments-ajax.php", map);
		Document document = Jsoup.parse(result);
		
		Element errorElment = document.getElementById("error-page");
		if(errorElment != null) {
			throw new HttpException("图片地址不正确");
		}
	}
	
	/**
	 * 发出Post请求。
	 * @param urlString 请求地址
	 * @param formData 文本参数
	 * @return 
	 * @throws Exception
	 */
	public static String doPost(String urlString, Map<String, String> formData) throws Exception {
		return doPost(urlString, formData, null, null);
	}
	
	public static String doPost(String urlString, Map<String, String> formData, FormFile[] files, Map<String, String> headers) throws Exception {
		log.d(urlString+"----"+formData);
		
		
		byte[] resultBytes = null;
		try {
			resultBytes = HttpRequester.post(urlString, formData, files, headers);
		} catch(InterruptedIOException e){
			throw new HttpTimeoutException();
		} catch(javax.net.ssl.SSLHandshakeException e){
			throw new HttpsCertificateException();
		}
		
		String result = new String(resultBytes);
		log.i("[urlString] Result : " + result);
		
		// 解析有无异常
		parseError(result);   
		
		return result;
	}
	
	/**
	 * 发出Post请求，允许同时上传文件
	 * @param urlString
	 * @param formData
	 * @param files
	 * @return
	 * @throws Exception
	 */
	public static String doPost(String urlString, Map<String, String> formData, FormFile[] files) throws Exception {
		return doPost(urlString, formData, files, null);
	}
	
	/**
	 * 发起GET请求
	 * @param urlString
	 * @param params
	 * @return
	 * @throws Exception
	 */
	public static String doGet(String urlString, Map<String, String> params) throws Exception {
		return doGet(urlString, params, null);
	}
	
	/**
	 * 发起GET请求，并可以定义HTTP的Header信息
	 * @param urlString
	 * @param params
	 * @param headers
	 * @return
	 * @throws Exception
	 */
	public static String doGet(String urlString, Map<String, String> params, Map<String, String> headers) throws Exception {
		log.d(urlString+"----"+urlString);
		byte[] resultBytes = null;
		try {
			resultBytes = HttpRequester.get(urlString, params, headers);
		} catch(InterruptedIOException e){
			throw new HttpTimeoutException();
		} catch(javax.net.ssl.SSLHandshakeException e){
			throw new HttpsCertificateException();
		}
		
		String result = new String(resultBytes);
		log.i("[urlString] Result : " + result);
		// 解析有无异常
		parseError(result);   
		
		return result;
	}

	private static void parseError(String result) throws JSONException, Exception {
		JSONObject json = new JSONObject(result);
		if(!json.getBoolean("ok")) {
			int errcode = json.optInt("ecode");
			String errmsg = json.optString("emsg");
			throw new HttpErrorCodeException(errmsg, errcode);
		}
	}
	
	
	public static Bitmap downloadBitmap(String url) throws Exception {
		try {
			HttpURLConnection postConnection = HttpRequester.requestGet(url, null, null);
			postConnection.setReadTimeout(60 * 1000);
			
			InputStream is = postConnection.getInputStream();
			ByteArrayOutputStream outStream = new ByteArrayOutputStream();

			byte[] buffer = new byte[1024];
	        int len = 0;
	        while ((len = is.read(buffer)) != -1) {
	            outStream.write(buffer, 0, len);
	        }
	        IOUtils.closeQuietly(is);
	        
	        byte[] arr = outStream.toByteArray();
	        IOUtils.closeQuietly(outStream);
	        
	        if(arr != null && arr.length > 0){
	        	return BitmapFactory.decodeByteArray(arr, 0, arr.length);
	        }
	        
		} catch(InterruptedIOException e){
			throw new HttpTimeoutException();
		} catch(javax.net.ssl.SSLHandshakeException e){
			throw new HttpsCertificateException();
		}
        
        return null;
	}
	
	public static void saveFile(String url, File file, ProgessCallback progessCallback) throws Exception {
		try {
			log.i(url);
			HttpURLConnection postConnection = HttpRequester.requestGet(url, null, null);
			postConnection.setReadTimeout(60 * 1000);
			
			InputStream is = postConnection.getInputStream();
			OutputStream os = new FileOutputStream(file);

			long totalLength = postConnection.getContentLength();
			long readedLength = 0;
			if(progessCallback != null) {
				progessCallback.onProgessChanged(readedLength, totalLength);
			}
			
			try {
				byte[] buffer = new byte[1024];
		        int len = -1;
		        while ((len = is.read(buffer)) != -1) {
		            os.write(buffer, 0, len);
		            readedLength += len;
		            if(progessCallback != null) {
						progessCallback.onProgessChanged(readedLength, totalLength);
					}
		            Thread.sleep(500);
		        }
			} finally {
				IOUtils.closeQuietly(is);
				IOUtils.closeQuietly(os);
			}
		} catch(InterruptedIOException e){
			throw new HttpTimeoutException();
		} catch(javax.net.ssl.SSLHandshakeException e){
			throw new HttpsCertificateException();
		}
	}
	
	/**
	 * 将接口返回的时间戳转换为Java的时间对象
	 * @param seconds
	 * @return
	 */
	public static Date toJavaDate(long seconds) {
		if(seconds > 0) {
			try {
				return new Date(seconds*1000L);
			} catch (Exception e) {
			}
		}
		return null;
	}
	
	/**
	 * 将Java的时间对象转换为接口时间戳
	 * @param date
	 * @return
	 */
	public static long toApiDate(Date date) {
		if(date != null) {
			try {
				return date.getTime()/1000;
			} catch (Exception e) {
			}
		}
		return 0;
	}
	
	/**
	 * 将Json数组对象转换为字符串数组对象
	 * @param jsonArray
	 * @return
	 */
	public static String[] toJavaArray(JSONArray jsonArray) {
		if(jsonArray != null) {
			String[] array = new String[jsonArray.length()];
			for (int i = 0; i < jsonArray.length(); i++) {
				array[i] = jsonArray.optString(i);
			}
			return array;
		}
		return null;
	}
	
}
